#include <deviceNormalParam.h>

// device normal parameter instance
struct deviceParameterNormalInform *devNorParmInst()
{
    static struct deviceParameterNormalInform deviceNormalParam;
    return &deviceNormalParam;
}

static const struct deviceParameterNormalInform defaultparam /*__attribute__((section(".text")))*/ =
    {
        .paramHead.paramSize = sizeof(struct deviceParameterNormalInform) - sizeof(struct deviceParameterCommonHead),
        .paramHead.paramCrc = 0,
        .deviceSerialNumber = "\0",
        .device485Addr = 0xff,
};

// do not save to hard. save to hard use other way.
int deviceNormalParamConfig(void *outParm, const void *inputParam, int configLevel)
{
    uint16_t tmpcrc16;
    struct deviceParameterNormalInform *desParm = (struct deviceParameterNormalInform *)outParm;
    const struct deviceParameterNormalInform *newParam = (const struct deviceParameterNormalInform *)inputParam;
    if (!outParm)
    {
        logerror("");
        return -1;
    }
    logdebug("config:%s,level:%d", (newParam == NULL) ? "reset" : "set", configLevel);
    if (newParam == NULL)
    {
        newParam = &defaultparam;
    }
    else
    {
        tmpcrc16 = calculateUint16CrcHash(newParam->deviceSerialNumber, newParam->paramHead.paramSize);
        if (tmpcrc16 != newParam->paramHead.paramCrc)
        {
            logerror("%x,%x", tmpcrc16, newParam->paramHead.paramCrc);
            return -1;
        }
    }
    switch (configLevel)
    {
    case DEVICE_PARAM_CONFIG_LEVEL_0:
    {
        // configOneParameterCommon(struct deviceParameterNormalInform, deviceSerialNumber);
    }
    case DEVICE_PARAM_CONFIG_LEVEL_1:
    {
        configOneParameterCommon(struct deviceParameterNormalInform, device485Addr);
    }
    case DEVICE_PARAM_CONFIG_LEVEL_2:
    {
    }
    case DEVICE_PARAM_CONFIG_LEVEL_3:
    {
    }
    case DEVICE_PARAM_CONFIG_LEVEL_4:
    {
    }
    case DEVICE_PARAM_CONFIG_LEVEL_5: // defualt
    {
    }
    case DEVICE_PARAM_CONFIG_LEVEL_6:
    {
    }
    case DEVICE_PARAM_CONFIG_LEVEL_7:
    {
    }
    case DEVICE_PARAM_CONFIG_LEVEL_8:
    {
    }
    case DEVICE_PARAM_CONFIG_LEVEL_9:
    {
    }
    default:
    {
        break;
    }
    }
    deviceParamCalculateHeadInform((struct deviceParameterCommonHead *)desParm, sizeof(struct deviceParameterNormalInform));
    return 0;
}

int deviceNormalParamPrint()
{
    struct deviceParameterNormalInform *tmpNormalParam = devNorParmInst();
    logdebug("printf device normal param------>");
    logdebug("size:%d", tmpNormalParam->paramHead.paramSize);
    logdebug("crc:%d", tmpNormalParam->paramHead.paramCrc);
    logdebug("sn:%s", getMaxSizeHexStr(tmpNormalParam->deviceSerialNumber).byteStr);
    logdebug("addr:%d", tmpNormalParam->device485Addr);
    return 0;
}

#define DEVICE_PARAM_PC_CHECK_SAVE_FILE "./deviceParamText.txt"
static int deviceReadParamCallPcCheck(struct deviceParameterCommonHead *paramdata, int paramAllSize)
{
    return readLocalFile(DEVICE_PARAM_PC_CHECK_SAVE_FILE, (char *)paramdata, paramAllSize);
}
static int deviceWriteParamCallPcCheck(struct deviceParameterCommonHead *paramdata, int paramAllSize)
{
    return writeLocalFile(DEVICE_PARAM_PC_CHECK_SAVE_FILE, (const char *)paramdata, paramAllSize);
}
struct deviceParameterOperate *devParamNormalOpt()
{
    static struct deviceParameterOperate paramNormalOpt =
        {.readcall = deviceReadParamCallPcCheck,
         .writecall = deviceWriteParamCallPcCheck,
         .configcall = deviceNormalParamConfig,
         .paramdata = NULL,
         .paramAllSize = sizeof(struct deviceParameterNormalInform)};
    if (!paramNormalOpt.paramdata)
    {
        paramNormalOpt.paramdata = (struct deviceParameterCommonHead *)devNorParmInst();
    }
    return &paramNormalOpt;
}
#if 0
#include <deviceNormalParam.h>

struct deviceParameterNormalInformOld
{
    struct
    {
        uint16_t paramSize;
        uint16_t paramCrc;
    };
    uint8_t deviceSerialNumber[DEVICE_SERIAL_NUMBER_SIZE]; // config by broadcast
};

struct deviceParameterNormalInformNew
{
    struct
    {
        uint16_t paramSize;
        uint16_t paramCrc;
    };
    uint8_t deviceSerialNumber[DEVICE_SERIAL_NUMBER_SIZE]; // config by broadcast
    uint8_t device485Addr;          // config by broadcast with device serial number
    uint8_t deviceip[4];
};

int main()
{
    struct deviceParameterNormalInformOld tmpparmOld;
    struct deviceParameterNormalInformNew tmpparmNew;
    char *tmpConstStr;
    // struct deviceParameterNormalInform *tmpNormalParam = devNorParmInst();
    logdebug("--------check read");
    deviceParamReadFromHard(devParamNormalOpt());
    deviceNormalParamPrint();
    logdebug("-------check write");
    deviceParamWriteToHard(devParamNormalOpt());
    deviceNormalParamPrint();
    logdebug("-------check modify");
    tmpConstStr = "12345678901234567890123456789012";
    memcpypro(devNorParmInst()->deviceSerialNumber, sizeof(devNorParmInst()->deviceSerialNumber), tmpConstStr, strlen(tmpConstStr));
    devNorParmInst()->device485Addr = 0x02;
    deviceNormalParamPrint();
    logdebug("-------check write new");
    deviceParamWriteToHard(devParamNormalOpt());
    deviceNormalParamPrint();
    logdebug("-------check new data");
    deviceParamReadFromHard(devParamNormalOpt());
    deviceNormalParamPrint();
    logdebug("-------check reset 1");
    deviceParamResetAndSave(devParamNormalOpt(), DEVICE_PARAM_CONFIG_LEVEL_1);
    deviceNormalParamPrint();
    logdebug("-------check reset 0");
    deviceParamResetAndSave(devParamNormalOpt(), DEVICE_PARAM_CONFIG_LEVEL_0);
    deviceNormalParamPrint();


    devNorParmInst()->device485Addr = 0x01;
    tmpConstStr = "ab345678901234567890123456789012";
    memcpypro(tmpparmOld.deviceSerialNumber, sizeof(tmpparmOld.deviceSerialNumber), tmpConstStr, strlen(tmpConstStr));
    tmpparmOld.paramSize = sizeof(tmpparmOld) - offsetof(struct deviceParameterNormalInformOld, deviceSerialNumber);
    tmpparmOld.paramCrc = calculateUint16CrcHash(tmpparmOld.deviceSerialNumber, tmpparmOld.paramSize);
    logdebug("-------check config shorter data");
    logdebug("%d,%d", tmpparmOld.paramSize, tmpparmOld.paramCrc);
    deviceNormalParamConfig(devNorParmInst(), (const struct deviceParameterNormalInform *)&tmpparmOld, 0);
    deviceNormalParamPrint();
    logdebug("-------check write shorter param");
    deviceParamWriteToHard(devParamNormalOpt());
    logdebug("-------check read shorter param");
    deviceParamReadFromHard(devParamNormalOpt());
    deviceNormalParamPrint();

    tmpConstStr = "fffffddddd";
    memcpypro(tmpparmNew.deviceSerialNumber, sizeof(tmpparmNew.deviceSerialNumber), tmpConstStr, strlen(tmpConstStr));
    tmpparmNew.device485Addr = 0x03;
    tmpConstStr = "fffffddddd";
    memcpypro(tmpparmNew.deviceip, sizeof(tmpparmNew.deviceip), tmpConstStr, strlen(tmpConstStr));
    tmpparmNew.paramSize = sizeof(tmpparmNew) - offsetof(struct deviceParameterNormalInformOld, deviceSerialNumber);
    tmpparmNew.paramCrc = calculateUint16CrcHash(tmpparmNew.deviceSerialNumber, tmpparmNew.paramSize);
    logdebug("-------check config longer data");
    logdebug("%d,%d", tmpparmNew.paramSize, tmpparmNew.paramCrc);
    deviceNormalParamConfig(devNorParmInst(), (const struct deviceParameterNormalInform *)&tmpparmNew, 0);
    deviceNormalParamPrint();
    logdebug("-------check write longer param");
    deviceParamWriteToHard(devParamNormalOpt());
    logdebug("-------check read longer param");
    deviceParamReadFromHard(devParamNormalOpt());
    deviceNormalParamPrint();
    
}
#endif
